<#############################
 # @author: Hauk Zero
 # @email: haukzero1@gmail.com
 # @version: PowerShell 7.4.6
 #############################>


$global:previousDir = $PWD.Path
$global:git_branch_cache = ""

<###################
 # Prompt with git
 ###################>
function Prompt {
    $currentDir = $PWD.Path

    if ($git_branch_cache -eq "" -or $currentDir -ne $previousDir) {
        $git_branch_cache = & {
            $ErrorActionPreference = 'SilentlyContinue'
            git rev-parse --abbrev-ref HEAD
        }
        $previousDir = $currentDir
    }

    $pattern = $env:userprofile -replace '\\', '\\'
    $promptString = "$(Get-Location)" -replace $pattern, "~ "

    if ($git_branch_cache) {
        $git_status = & {
            $ErrorActionPreference = 'SilentlyContinue'
            git status --porcelain
        }
        if ($git_status) {
            $git_branch_cache += " ✗"
        } else {
            $git_branch_cache += " ✓"
        }
    }

    "`e[1;32m" + $promptString + "`e[1;36m" + " $git_branch_cache" + "`e[m`e[1;32m`n❯`e[m "
}

<###################
 # General Settings
 ###################>
Set-Alias -Name mk -Value mkdir
Set-Alias -Name ll -Value ls
Set-Alias -Name l -Value ls
Remove-Item alias:cd

function cd {
    param (
        [string]$path
    )

    if ($path -eq '-') {
        echo $global:previousDir
        $target = $global:previousDir
        $global:previousDir = $PWD.Path
        Set-Location $target
    } else {
        $global:previousDir = $PWD.Path
        Set-Location $path
    }
}
function cdd {
    cd E:\Desktop
}
function vi {
    param (
        [string]$path,
        [string]$vimPath = 'D:\Program Files (x86)\Git\usr\bin\vim.exe'
    )
    Start-Process $vimPath $path
}
function touch {
    param (
        [string[]]$paths
    )
    foreach ($path in $paths) {
        if (Test-Path $path) {
            (Get-Item $path).LastWriteTime = Get-Date
        }
        else {
            New-Item -ItemType File -Path $path
        }
    }
}
function rmf {
    param (
        [string[]]$paths,
        [string[]]$exclude,
        [switch]$help
    )
    if ($help) {
        Write-Output "Usage: [delete specific files] rmf -paths @('file1.txt', 'file2.txt')"
        Write-Output "       [delete all files except specified files] rmf -exclude @('a.txt', 'b.txt')"
        return
    }
    if ($paths -and $paths.Count -gt 0) {
        # Delete specified files
        foreach ($path in $paths) {
            if (Test-Path $path) {
                Remove-Item $path -Force -Recurse
            }
        }
    } 
    elseif ($exclude -and $exclude.Count -gt 0) {
        # Delete all files in current directory except specified files
        $items = Get-ChildItem -File
        foreach ($item in $items) {
            if ($exclude -contains $item.Name) {
                continue
            }
            Remove-Item $item.FullName -Force
        }
    }
}
function .. {
    cd ..
}
function ... {
    cd ../..
}
function ari {
    param (
        [string]$url
    )
    aria2c.exe -x 16 $url
}
function cm {
    cd "E:\Program Data\huggingface\models"
}

function Set-Proxy {
    $env:http_proxy="127.0.0.1:7890"
    $env:https_proxy="127.0.0.1:7890"
}

function Clear-Proxy {
    $env:http_proxy=""
    $env:https_proxy=""
}

function Show-Tree {
    param (
        [string]$Path = (Get-Location)
    )

    $items = Get-ChildItem -Path $Path -Recurse | Sort-Object FullName
    $indent = 0

    foreach ($item in $items) {
        $level = $item.FullName.Split('\').Count - $Path.Split('\').Count - 1
        $indentation = '.' * ($level * 1)

        if ($item.PSIsContainer) {
            Write-Host "$indentation+ $($item.Name)"
        } else {
            Write-Host "$indentation- $($item.Name)"
        }
    }
}
# Set-Alias -Name treee -Value Show-Tree
function treee {
    param (
        [string]$Path = (Get-Location),
        [switch]$ascii
    )
    if ($ascii) {
        tree /F /A $Path
    }
    else {
        tree /F $Path
    }
}


<###################
 # Docker Alias
 ###################>
function de {
    param (
        [string]$container
    )
    docker exec -it $container bash
}
function dis {
    docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}"
}
function dps {
    docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Status}}"
}
function dr {
    param(
        [string]$image,
        [string]$name,
        [string[]]$volumes = @(),
        [string[]]$ports = @(),
        [string]$workdir = "/root/workspace",
        [switch]$help
    )

    if ($help) {
        Write-Output "Usage: dr -name <container_name> -volumes @('host_path1:container_path1', 'host_path2:container_path2') -p @('host_port:container_port') -image <image>"
        return
    }

    $volumeOptions = ($volumes | ForEach-Object { "-v $_" }) -join ' '
    $portOptions = ($ports | ForEach-Object { "-p $_" }) -join ' '

    $command = "docker run -itd --gpus all --net=host -w $workdir --name $name $volumeOptions $portOptions $image"
    
    Invoke-Expression $command
}

<###################
 # Python Alias
 ###################>
Set-Alias -Name py -Value python
function pg {
    param (
        [string]$name
    )
    pip list | Select-String $name
}
function pii {
    pip install -U
}
function pl {
    pip list
}
function pn {
    $packages = pip list
    $packageCount = ($packages | Measure-Object -Line).Lines - 2
    return $packageCount
}
function pu {
    pip install --upgrade
}
